var compressor = require('node-minify'),
    fs = require("fs"),
    express = require("express"),
    crypto = require("crypto"),
    ejs = require('ejs'),
    path = require('path'),
    mime = require('mime'),
    app = express(),
    classes_directory = "../src/classes",
    libs_directory = "../src/libs",
    style_file = "../src/assets/css/style.css";

app.use(express.bodyParser());
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.engine('html', ejs.renderFile);

var files = [],
    files_md5 = [],
    files_for_compress = [];

function generatePackage(files_c, callback){
    compressFiles(files_c, callback);
}

function compressFiles(files_c, callback){
    var tmp = files_for_compress.slice(0), //create new array with all libs
        step = 1;
    //push Base.js on top after libs
    tmp.push(classes_directory+"/View.js");
    tmp.push(classes_directory+"/Views.js");
    tmp.push(classes_directory+"/Base.js");
    tmp.push(classes_directory+"/Mobile.js");
    //add all classes selected form user
    files_c.forEach(function(item, index, files){
        //skip Base.js
        if(["Base.js", "Mobile.js", "View.js", "Views.js", "Application.js"].indexOf(item) < 0){
            tmp.push(classes_directory+"/"+item);
        }
    });
    tmp.push(classes_directory+"/Application.js");
    //combine and minify all files
    new compressor.minify({
        type: "gcc",
        options: [
            "--language_in", "ECMASCRIPT5"
        ],
        fileIn: tmp,
        fileOut: "mini/androjs-min-0.1"+Date.now()+".js",
        callback: function(err){
            var _this = this, md5sum,
                shasum = crypto.createHash('md5'),
                file_path = "";
            if(err) {
                console.log(err);
            }
            else {
                console.log('File "' + this.fileOut + '" is READY');
                //read stream of generated file
                fs.createReadStream(this.fileOut, {encoding: 'binary'})
                    .on('data', function(data){
                        shasum.update(data);
                    })
                    .on('end', function(){
                        //get file md5
                        md5sum = shasum.digest('hex');
                        file_path = _this.fileOut;
                        //check this file md5 sum in already generated files
                        files_md5.forEach(function(item){
                            //if we have this md5 sum use already generated file
                            if(item.md5 === md5sum){
                                file_path = item.path;
                                fs.unlink(_this.fileOut); //remove this new generated file because we already have one
                                return;
                            }
                        });
                        //Push this file and md5 sum if we don't have this file generated
                        if(file_path === _this.fileOut){
                            files_md5.push({ md5 : md5sum, path: file_path});
                        }
                        //Return property file path
                        callback(file_path);
                    });
            }

        }
    });
}

//Delete all generated files on server restart
fs.readdir("mini", function(err, files){
    files.forEach(function(file){
        fs.unlink("mini/"+file);
    });
});
//Get all classes files
fs.readdir(classes_directory, function(err, fiels){
    files = fiels;
    console.log(files);
});
//Get all libs files
fs.readdir(libs_directory, function(err, fiels){
    files_for_compress = fiels;
    files_for_compress.forEach(function(item, index){
        files_for_compress[index] = libs_directory+"/"+item;
    })
});

app.get('/', function(req, res){
    res.render('index.html', { files: files })
});

app.post('/generate_package', function(req, res){
    generatePackage(req.body.files, function(file){
        var filename = path.basename(file);
        //get file name and send to user
        res.send(filename);
    });
});

app.get('/get_file/:filename', function(req, res){
    var filename = req.params.filename,
        file = "mini/"+req.params.filename,
        mimetype = mime.lookup(filename);

    res.setHeader('Content-disposition', 'attachment; filename=' + file);
    res.setHeader('Content-type', mimetype);
    //download requested file
    var filestream = fs.createReadStream(file);
    filestream.pipe(res);
});

app.listen(3000);